package com.ruoyi.gis.earthai.controller;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.aiearth_engine20220609.models.CreateAIJobResponseBody;
import com.aliyun.aiearth_engine20220609.models.DownloadDataResponseBody;
import com.aliyun.aiearth_engine20220609.models.ListDatasResponseBody;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.ZipUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.minio.MinioFile;
import com.ruoyi.framework.minio.MinioService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.gis.componets.EarthAiComponent;
import com.ruoyi.gis.domain.Area;
import com.ruoyi.gis.earthai.service.EarthDataApiService;
import com.ruoyi.gis.earthai.vo.*;
import com.ruoyi.gis.service.IAreaService;
import com.ruoyi.gis.service.IDatasetRasterService;
import com.ruoyi.gis.utils.GeoUtils;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTWriter;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/earthai")
public class EarchAiController extends BaseController {

    @Autowired
    private EarthDataApiService earthDataApiService;
    @Autowired
    private IAreaService areaService;
    @Autowired
    private MinioService minioService;
    @Autowired
    private RuoYiConfig ruoYiConfig;
    @Autowired
    private IDatasetRasterService datasetRasterService;
    @Autowired
    private EarthAiComponent earthAiComponent;
    @Autowired
    TokenService tokenService;


    @Deprecated
    @PostMapping("/initArea")
    public AjaxResult initArea(){
        List<Area> provinces = areaService.selectProvinceList();
        if(provinces==null)return AjaxResult.success();
        provinces.stream().forEach(province->{
            List<Area> cities
                    = areaService.selectCityList(province.getName());
            Area p = new Area();
            p.setId(IdUtil.getSnowflakeNextIdStr());
            p.setName(province.getName());
            p.setEname(province.getEname());
            p.setCode(province.getCode());
            p.setGeom(province.getGeom());
            p.setLevel(1);
            p.setPname("中国");
            p.setPcode("000000");
            p.setPid("0");
            areaService.insertArea(p);
            if(cities!=null&& cities.size()>0){
                cities.stream().forEach(city->{
                    Area c = new Area();
                    c.setId(IdUtil.getSnowflakeNextIdStr());
                    c.setName(city.getName());
                    c.setEname(city.getEname());
                    c.setCode(city.getCode());
                    c.setGeom(city.getGeom());
                    c.setLevel(2);
                    c.setPname(province.getName());
                    c.setPcode(province.getCode());
                    c.setPid(p.getId());
                    areaService.insertArea(c);
                    List<Area> districts
                            = areaService.selectDistrictList(province.getName(),city.getName());
                    if(districts!=null&& districts.size()>0){
                        districts.stream().forEach(district->{
                            Area d = new Area();
                            d.setId(IdUtil.getSnowflakeNextIdStr());
                            d.setName(district.getName());
                            d.setEname(district.getEname());
                            d.setCode(district.getCode());
                            d.setGeom(district.getGeom());
                            d.setLevel(3);
                            d.setPname(city.getName());
                            d.setPcode(city.getCode());
                            d.setPid(c.getId());
                            areaService.insertArea(d);
                        });
                    }
                });
            }
        });
        int a = areaService.insertArea(new Area());
        return AjaxResult.success();
    }


    @GetMapping("/parseArea/{areaId}")
    public AjaxResult parseArea(@PathVariable("areaId")String areaId){
        String wkt = areaService.selectWktByAreaId(areaId);
        String json = GeoUtils.wktToJson(wkt);
        return AjaxResult.success("查询成功",json);
    }


    @PostMapping("/parseShpFile")
    public AjaxResult parseShpFile(
            @RequestBody MinioFile minioFile) throws IOException {
        ResponseEntity<byte[]> download = minioService.
                download(minioFile.getBucket(), minioFile.getObjectName());
        File bucketFolder = new File(ruoYiConfig.getMinioLocalDir(),minioFile.getBucket());
        File zipFile = new File(bucketFolder,minioFile.getFileName());
        FileUtils.writeByteArrayToFile(zipFile,download.getBody());
        //解析shp文件
        File shpFolder = new File(bucketFolder,FileUtils.getNameNotSuffix(minioFile.getFileName()));
        ZipUtils.unzip(zipFile,shpFolder.getPath());
        File shpFile = FileUtils.getFirstFileByExt(shpFolder,"shp");
        if(shpFile==null){
            return AjaxResult.error("未找到shp文件");
        }
        // Read the shapefile
        FileDataStore store = FileDataStoreFinder.getDataStore(shpFile);
        SimpleFeatureSource source = store.getFeatureSource();
        SimpleFeatureCollection featureCollection = source.getFeatures();
        SimpleFeatureType schema = source.getSchema();
        //geoGson
        ByteArrayOutputStream outputStreamGson = new ByteArrayOutputStream();
        FeatureJSON featureJSON =
                new FeatureJSON(new GeometryJSON(20));// 此处会控制生成geojson的坐标的小数点精度
        // Convert features to WKT
        WKTWriter wktWriter = new WKTWriter();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        String shpWkt = null;
        String shoGeoGson = null;
        JSONObject geoJsonObject=new JSONObject();
        geoJsonObject.put("type","FeatureCollection");
        List<JSONObject> array  = new ArrayList<JSONObject>();
        try (SimpleFeatureIterator features = featureCollection.features()) {
//            StringWriter writer = new StringWriter();
//            writer.write("{\"type\":\"FeatureCollection\",\"crs\":");
//            featureJSON.writeCRS(schema.getCoordinateReferenceSystem(), writer);
//            writer.write(",");
//            writer.write("\"features\":");
//            writer.write("[");
            while (features.hasNext()) {
                SimpleFeature feature = features.next();
                String wkt = wktWriter.write((Geometry) feature.getDefaultGeometry());
                outputStream.write((wkt + "\n").getBytes());

                StringWriter writer = new StringWriter();
                featureJSON.writeFeature(feature, writer);
                String temp = writer.toString();
//                byte[] b = temp.getBytes("utf-8");
//                temp = new String(b, "utf-8");
                JSONObject json = JSONObject.parseObject(temp);
                array.add(json);
//                featureJSON.writeFeature(feature, writer);
//                if (features.hasNext())
//                    writer.write(",");
            }
            shpWkt = outputStream.toString();
//            shoGeoGson = writer.toString();
            //添加到geojsonObject
            geoJsonObject.put("features",array);
//            featureJSON.writeFeatureCollection(featureCollection, outputStreamGson);
//            shoGeoGson = outputStreamGson.toString();
        } finally {
            // Clean up temporary files
            store.dispose();
            FileUtils.deleteDirectory(shpFolder);
        }
        JSONObject data = new JSONObject();
        data.put("geoGson", JSON.toJSONString(geoJsonObject));
//        data.put("geoGson", shoGeoGson);
        data.put("wkt",shpWkt);
        return AjaxResult.success("解析成功",data);
    }
    //查询公开数据
    @PostMapping("/listDatas")
    public TableDataInfo listDatas(
           @RequestBody ListDataVo listDataVo)
    {
//        PageDomain pageDomain = TableSupport.buildPageRequest();
//        Integer pageNum = pageDomain.getPageNum();
//        Integer pageSize = pageDomain.getPageSize();
        String wkt = "";
        if(ListDataVo.type_area.equals(listDataVo.getSearchType())){
            //根据区域获取区域的wkt
            wkt = areaService.selectWktByAreaId(listDataVo.getAreaId());
        }else if(ListDataVo.type_draw.equals(listDataVo.getSearchType())){
            wkt = GeoUtils.geoGsonToWkt(listDataVo.getIntersectsGeojson());
        }else if(ListDataVo.type_shp.equals(listDataVo.getSearchType())){
            wkt = listDataVo.getIntersectsGeojson();
        }
        ListDatasResponseBody data = earthDataApiService
                .listDatas(listDataVo.getSourceTypeList(),
                        wkt,
                        listDataVo.getDateStart(),
                        listDataVo.getDateEnd(),
                        listDataVo.getCloudageMin(),
                        listDataVo.getCloudageMax(),
                        listDataVo.getPageSize(),
                        listDataVo.getPageNum());
        TableDataInfo rspData = new TableDataInfo();
        if(data!=null&&data.getList()!=null){
            //datasetRasterService.addDatasetRaster(data);
            rspData.setCode(HttpStatus.SUCCESS);
            rspData.setMsg("查询成功");
            rspData.setRows(data.getList().stream()
                    .sorted((o1, o2) -> o2.getRaster().getAcquisitionDateStart().
                            compareTo(o1.getRaster().getAcquisitionDateStart()))
                    .collect(Collectors.toList()));
            rspData.setTotal(data.getTotalCount());
            earthAiComponent.sendSaveRasterInfoMessage(data.getList());
        }else {
            rspData.setCode(HttpStatus.ERROR);
            rspData.setMsg("查询失败");
        }
        return rspData;
    }
    //根据搜索结果的数据唯一ID，下载已有数据，如果数据需要准备，
    // 需要轮询调用直到finished字段为true后，下载链接才会生成，链接生成后会扣除用户的数据下载流量，请酌情调用。
    @Deprecated
    @PostMapping("/downloadData")
    public AjaxResult downloadData(
            @RequestBody DownloadDataVo downloadDataVo, HttpServletResponse response)
    {
//        PageDomain pageDomain = TableSupport.buildPageRequest();
//        Integer pageNum = pageDomain.getPageNum();
//        Integer pageSize = pageDomain.getPageSize();
        DownloadDataResponseBody responseBody = earthDataApiService.
                downlaodData(downloadDataVo.getDataId());
        return AjaxResult.success("操作成功",responseBody);
    }
    @PostMapping("/collectData")
    public AjaxResult collectData(HttpServletRequest request,
            @RequestBody CollectDataVo collectDataVo, HttpServletResponse response)
    {
//        PageDomain pageDomain = TableSupport.buildPageRequest();
//        Integer pageNum = pageDomain.getPageNum();
//        Integer pageSize = pageDomain.getPageSize();
        LoginUser loginUser = tokenService.getLoginUser(request);
        earthDataApiService.datasetRasterCollectService(collectDataVo,loginUser);
        return AjaxResult.success("操作成功");
    }

    //我们自己训练，不用阿里云的
    @Deprecated
    @PostMapping("/createAIJob")
    public AjaxResult createAIJob(
            @RequestBody CreateAiJobVo createAiJobVo, HttpServletResponse response)
    {
//        PageDomain pageDomain = TableSupport.buildPageRequest();
//        Integer pageNum = pageDomain.getPageNum();
//        Integer pageSize = pageDomain.getPageSize();
        CreateAIJobResponseBody responseBody = earthDataApiService.createAIJob(createAiJobVo);
        return AjaxResult.success("操作成功",responseBody);
    }


}
